package com.lwl.nio;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.GatheringByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Marketing {

	// These are just representative; add your own
	private static String[] col1 = { "Aggregate", "Enable", "Leverage", "Facilitate", "Synergize", "Repurpose",
			"Strategize", "Reinvent", "Harness" };
	private static String[] col2 = { "cross-platform", "best-of-breed", "frictionless", "ubiquitous", "extensible",
			"compelling", "mission-critical", "collaborative", "integrated" };
	private static String[] col3 = { "methodologies", "infomediaries", "platforms", "schemas", "mindshare", "paradigms",
			"functionalities", "web services", "infrastructures" };
	
	private static final String DEMOGRAPHIC = "nio.txt";
	
	private static String newline = System.getProperty ("line.separator");

	public static void main(String[] args) throws IOException {
		int reps = 50000;
		long start = System.nanoTime();
		//nioChannel(reps);       //8975402124  119251333  129980667
		//nioChannel2(reps);    //535929831   582175545  556276902
		nioChannel2(reps);      //501871290   504541919  499730785
		//ioWrite(reps);        //785437465   830881953  834051366
		long time = System.nanoTime() - start;
		System.out.println("耗时: "+time);
	}
	
	private static void ioWrite(int reps) throws FileNotFoundException, IOException {
		FileOutputStream fos = new FileOutputStream("io.txt");
		for (int i = 0; i < reps; i++) {
			String string1 = col1[rand.nextInt(col1.length)];
			String string2 = col1[rand.nextInt(col1.length)];
			String string3 = col1[rand.nextInt(col1.length)];
			fos.write(string1.getBytes());
			fos.write(" ".getBytes());
			fos.write(string2.getBytes());
			fos.write(" ".getBytes());
			fos.write(string3.getBytes());
			fos.write(newline.getBytes());
			fos.flush();
		}
		fos.close();
	}

	private static void nioChannel2(int reps) throws IOException {
		FileOutputStream fos = new FileOutputStream(DEMOGRAPHIC);
		FileChannel channel = fos.getChannel();
		for (int i = 0; i < reps; i++) {
			String string1 = col1[rand.nextInt(col1.length)];
			String string2 = col2[rand.nextInt(col2.length)];
			String string3 = col3[rand.nextInt(col3.length)];
			ByteBuffer put = ByteBuffer.allocate(string1.getBytes().length).put(string1.getBytes());
			ByteBuffer put2 = ByteBuffer.allocate(string2.getBytes().length).put(string2.getBytes());
			ByteBuffer put3 = ByteBuffer.allocate(string3.getBytes().length).put(string3.getBytes());
			put.flip();
			put2.flip();
			put3.flip();
			ByteBuffer[] byteBuffers = new ByteBuffer[]{put,put2,put3};
			long writed = 0;
			while ((writed = channel.write(byteBuffers)) > 0){
			}
		}
		//System.out.println ("Mindshare paradigms synergized to "+ DEMOGRAPHIC);
		fos.close( );
	}



	private static void nioChannel(int reps) throws FileNotFoundException, IOException {
		FileOutputStream fos = new FileOutputStream(DEMOGRAPHIC);
		GatheringByteChannel gatheringByteChannel = fos.getChannel();
		ByteBuffer[] bs = utterBS(reps);
		long hasWrite;
		while ((hasWrite = gatheringByteChannel.write(bs)) > 0) {
			//Logger.getLogger("lwl").info("has write "+hasWrite);
		}
		//System.out.println ("Mindshare paradigms synergized to "+ DEMOGRAPHIC);
		fos.close( );
	}
	
	private static ByteBuffer[] utterBS(int howMany){
		LinkedList<ByteBuffer> linkedList = new LinkedList<>();
		for (int i = 0; i < howMany; i++) {
			linkedList.add(pickRandom(col1, " "));
			linkedList.add(pickRandom(col2, " "));
			linkedList.add(pickRandom(col3, newline));
		}
		ByteBuffer[] bufs = new ByteBuffer[linkedList.size()];
		linkedList.toArray(bufs);
		return bufs;
	}
	
	private static Random rand = new Random( );
	/**
	 * 从String数组中随机获取一个String,和suffix同时存放到ByteBuffer中
	 * @param strings
	 * @param suffix
	 * @return
	 */
	private static ByteBuffer pickRandom(String[] strings,String suffix){
		String string = strings[rand.nextInt(strings.length)];
		int total = string.length() + suffix.length();
		ByteBuffer buf = ByteBuffer.allocateDirect(total);
		buf.put(string.getBytes());
		buf.put(suffix.getBytes());
		buf.flip();
		return buf;
	}
	
}
